// 地图对象
// 创建地图构造函数
function Map(width, height, bgcolor, position) {
    // 地图对象需要什么属性
    // 宽度
    this.width = width;
    // 高度
    this.height = height;
    // 背景颜色
    this.bgcolor = bgcolor;
    // 定位方式
    this.position = position;
    // 使用一个属性保存地图的dom对象
    this.el = null;
}

// 地图对象需要什么方法
// 显示地图在body中的方法
Map.prototype.show = function () {
    // 创建一个div,我们使用div标签绘制地图
    this.el = document.createElement("div");

    // 根据属性值设置相关CSS样式
    this.el.style.width = this.width + "px";
    this.el.style.height = this.height + "px";
    this.el.style.backgroundColor = this.bgcolor;
    this.el.style.position = this.position;
    // 把地图追加body标签
    document.body.appendChild(this.el);
}


// 食物构造函数
function Food(width, height, bgcolor, position) {
    // 食物需要什么属性
    // 宽度
    this.width = width;
    // 高度
    this.height = height;
    // 背景颜色
    this.bgcolor = bgcolor;
    // 定位方式
    this.position = position;
    // 食物水平坐标
    this.x = 0;
    // 食物垂直坐标
    this.y = 0;
    // 食物对应dom元素
    this.el = null;
}

// 食物方法
// 把食物显示地图地图上
Food.prototype.show = function () {
    if (this.el == null) {
        // 创建一个div,我们使用div标签绘制地图
        this.el = document.createElement("div");

        // 根据属性值设置相关CSS样式
        this.el.style.width = this.width + "px";
        this.el.style.height = this.height + "px";
        this.el.style.backgroundColor = this.bgcolor;
        this.el.style.position = this.position;

        // 把食物追加地图中
        map.el.appendChild(this.el);
    }

    // 得到食物随机坐标
    this.randomPos();

    // 设置食物位置
    this.el.style.left = this.x * 20 + "px";
    this.el.style.top = this.y * 20 + "px";
}

// 得到食物随机坐标方法
Food.prototype.randomPos = function () {
    // 得到0~39之间的随机整数
    this.x = Math.floor(Math.random() * 40);
    // 得到0~29之间的随机整数
    this.y = Math.floor(Math.random() * 30);
}


// 蛇构造函数
function Snake() {
    // 蛇属性

    // 蛇数据
    this.snakeData = [
        // [水平坐标,垂直坐标,背景颜色,定位方式,蛇数据对应的dom对象],
        [2, 1, "orange", "absolute", null],// 蛇头
        [1, 1, "green", "absolute", null],// 蛇节
        [1, 0, "green", "absolute", null],// 蛇节
        [0, 0, "green", "absolute", null],// 蛇节
    ];

    // 每个蛇节和蛇头的宽度高度
    this.width = 20;
    this.height = 20;

    // 蛇运动的方向,默认向右
    this.direction = "right";
}

// 蛇显示在地图中的方法
Snake.prototype.show = function () {
    // 缓存this
    var self = this;

    // 遍历蛇数据
    this.snakeData.forEach(function (item) {
        if (item[4] == null) {// 判断蛇数据对应的dom对象是否存在
            // 创建蛇对应的每一节dom对象
            item[4] = document.createElement("div");

            // 设置相关样式
            item[4].style.width = self.width + "px";
            item[4].style.height = self.height + "px";
            item[4].style.backgroundColor = item[2];
            item[4].style.position = item[3];

            // 把蛇节追加地图中
            map.el.appendChild(item[4]);
        }

        // 设置蛇节坐标位置
        item[4].style.left = item[0] * 20 + "px";
        item[4].style.top = item[1] * 20 + "px";
    })
}


// 蛇在地图移动的方法
Snake.prototype.move = function () {
    // 先假设蛇向右运动

    // 改变除蛇头之外其他蛇节数据,从蛇尾开始改
    for (var i = this.snakeData.length - 1; i >= 1; i--) {
        // 蛇节数据的x坐标
        this.snakeData[i][0] = this.snakeData[i - 1][0];
        // 蛇节数据的y坐标
        this.snakeData[i][1] = this.snakeData[i - 1][1];
    }

    // 根据蛇运动方向改变蛇头坐标
    if (this.direction == "right") {
        this.snakeData[0][0]++;
    } else if (this.direction == "left") {
        this.snakeData[0][0]--;
    } else if (this.direction == "up") {
        this.snakeData[0][1]--;
    } else if (this.direction == "down") {
        this.snakeData[0][1]++;
    }

    // 重新显示蛇
    this.show();

    // 判断蛇是否吃到食物
    this.eat();

    // 判断蛇是否出界
    this.border();

    // 判断蛇是否吃到自己
    this.suicide();
}

// 蛇吃食物的方法
Snake.prototype.eat = function () {
    // 当蛇头的坐标跟食物坐标重合的时候,那就是蛇吃到了食物
    if (this.snakeData[0][0] == food.x && this.snakeData[0][1] == food.y) {
        // 吃到了食物,蛇变长1格
        this.snakeData.push([-1, -1, "green", "absolute", null]);
        // 食物重新生成
        food.show();
    }
}


// 蛇移动的时候,判断蛇是否出界
Snake.prototype.border = function () {
    // 蛇头x坐标
    var SnakeX = this.snakeData[0][0];

    // 蛇头y坐标
    var SnakeY = this.snakeData[0][1];

    if (SnakeX > 39 || SnakeX < 0 || SnakeY > 29 || SnakeY < 0) {
        alert("撞墙了,游戏结束");
        // 清除定时器
        window.clearInterval(timer);
    }
}

// 蛇移动的时候,判断蛇是否吃到自己
Snake.prototype.suicide = function () {
    // 蛇头跟蛇节重合的时候,就表示自己吃到自己,蛇数据长度大于4

    // 蛇头x坐标
    var SnakeX = this.snakeData[0][0];

    // 蛇头y坐标
    var SnakeY = this.snakeData[0][1];

    for (var j = this.snakeData.length - 1; j >= 4; j--) {
        if (this.snakeData[j][0] == SnakeX && this.snakeData[j][1] == SnakeY) {
            alert("吃到自己了,游戏结束");
            // 清除定时器
            window.clearInterval(timer);
        }
    }
}

// 实例化地图对象
var map = new Map(800, 600, "#cccccc", "relative");
// 调用显示地图的方法
map.show();

// 实例化食物对象
var food = new Food(20, 20, "red", "absolute");
// 调用显示食物的方法
food.show();

// 实例化蛇对象
var snake = new Snake();
// 调用显示蛇的方法
snake.show();

// 按下键盘w a s d键可以改变蛇运动方向
document.onkeydown = function (e) {
    var e = e || window.event;

    if (e.keyCode == 87) {
        if (snake.direction != "down") {
            snake.direction = "up";
        }
    } else if (e.keyCode == 83) {
        if (snake.direction != "up") {
            snake.direction = "down";
        }
    } else if (e.keyCode == 65) {
        if (snake.direction != "right") {
            snake.direction = "left";
        }
    } else if (e.keyCode == 68) {
        if (snake.direction != "left") {
            snake.direction = "right";
        }
    }
}

var timer = window.setInterval(function () {
    snake.move();
}, 100);